import 'package:eh_mobile/common/utils/index.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_svg/svg.dart';
import '../../../../common/values/svg_image.dart';
import 'card_shake_widget.dart';

typedef StaggeredDraggableSortChange = void Function(
    int moveIndex, int toIndex);
typedef StaggeredDraggableCardOPen = void Function(int index, bool open);

// 拖拽排序view
class StaggeredDraggableSortView extends StatefulWidget {
  const StaggeredDraggableSortView(
      {super.key,
      this.itemSpace = 8,
      this.columnNum = 2,
      this.padding = const EdgeInsets.fromLTRB(14, 10, 14, 0),
      this.aspectRatio = 1,
      this.duration = const Duration(milliseconds: 300),
      this.canDrag = true,
      this.curve = Curves.easeOut,
      required this.staggeredModelList,
      this.itemExchanged,
      this.cardOpenChanged});
  final double itemSpace;
  final int columnNum;
  final EdgeInsets padding; //
  final Duration duration; // 动画执行时间
  final double aspectRatio; //宽高比
  final bool canDrag; // 是否可以拖拽
  final List<StaggeredItem> staggeredModelList;
  final Curve curve; //动画速率
  final StaggeredDraggableSortChange? itemExchanged; // 元素交换
  final StaggeredDraggableCardOPen? cardOpenChanged; // 卡片展开合上

  @override
  State<StaggeredDraggableSortView> createState() {
    return _StaggeredDraggableSortViewState();
  }
}

class _StaggeredDraggableSortViewState extends State<StaggeredDraggableSortView>
    with SingleTickerProviderStateMixin {
  double _itemMaxWidth = 0; //最大宽度
  double _itemMaxHeight = 0; //最大宽度
  double _itemMiniWidth = 0; //最小宽度
  double _itemMiniHeight = 0; //最小高度
  final List<StaggeredItem> _itemList = [];
  final List<StaggeredItem> _changeitemList = [];
  final List<String> _globalKeyList = [];

  // 卡片是否是打开状态
  bool _cardOpen = false;

  StaggeredItem? _moveStaggeredItem;

  late AnimationController _controller;

  int _moveIndex = 0; //移动的下标
  int _toIndex = 0; // 移动至目标的下标

  late double _mainY = widget.padding.top;

  final _offsetMap = <String, Offset>{};
  final _sizeMap = <String, Size>{};

  EdgeDraggingAutoScroller? _autoScroller;
  ScrollableState? _scrollable;
  Offset _dragPosition = Offset.zero;
  Offset _dragOffset = Offset.zero;

  @override
  void initState() {
    int maxCellCount = 0;
    _itemList.addAll(widget.staggeredModelList);
    _changeitemList.addAll(widget.staggeredModelList);

    for (var i = 0; i < _itemList.length; i++) {
      StaggeredItem element = widget.staggeredModelList[i];
      element.index = i;
      _globalKeyList.add(element.key!);
      if (maxCellCount < element.mainAxisCellCount!) {
        maxCellCount = element.mainAxisCellCount!;
      }
      if (maxCellCount < element.crossAxisCellCount!) {
        maxCellCount = element.crossAxisCellCount!;
      }
    }

    _itemMaxWidth = (1.sw -
            widget.padding.left -
            widget.padding.right -
            (widget.columnNum - 1) * widget.itemSpace) /
        widget.columnNum;
    _itemMaxHeight = _itemMaxWidth * widget.aspectRatio;

    _itemMiniWidth =
        (_itemMaxWidth - (maxCellCount - 1) * widget.itemSpace) / maxCellCount;
    _itemMiniHeight =
        (_itemMaxHeight - (maxCellCount - 1) * widget.itemSpace) / maxCellCount;

    _changeOffsetAndSizeMap();

    _controller = AnimationController(
      lowerBound: 0.0,
      upperBound: 1.0,
      vsync: this,
      duration: widget.duration,
    )..addListener(() {
        if (_controller.isCompleted) {
          // _itemList.clear();
          // _itemList.addAll(_changeitemList);
          // _changeitemList.clear();
          _controller.reset();
        }
        // setState(() {});
      });

    super.initState();
  }

  @override
  void didUpdateWidget(covariant StaggeredDraggableSortView oldWidget) {
    _itemList.clear();
    _itemList.addAll(widget.staggeredModelList);
    for (var i = 0; i < _itemList.length; i++) {
      StaggeredItem element = widget.staggeredModelList[i];
      element.index = i;
    }
    super.didUpdateWidget(oldWidget);
  }

  @override
  Widget build(BuildContext context) {
    if (_scrollable == null) {
      _scrollable = Scrollable.of(context);
      _autoScroller = EdgeDraggingAutoScroller(
        _scrollable!,
        onScrollViewScrolled: () {
          // _autoScroller?.startAutoScrollIfNecessary(dragTargetRect(100, 100));
        },
      );
    }

    var sc = Scrollable.of(context);

    return AnimatedContainer(
      height: _mainY,
      // color: Colors.white,
      duration: const Duration(milliseconds: 300),
      curve: _cardOpen ? widget.curve : Curves.easeInQuad,
      width: 1.sw,
      child: Stack(children: _buildItemWidgets()),
    );
  }

  List<Widget> _buildItemWidgets() {
    var widgets = <Widget>[];

    for (var i = 0; i < _itemList.length; i++) {
      // StaggeredItem staggeredModel = widget.staggeredModelList[i];
      // Offset? offset = _offsetMap['${staggeredModel.index}'];

      // Widget positionedText = AnimatedPositioned(
      //     duration: widget.duration,
      //     left: offset!.dx + 80,
      //     top: offset.dy + 20,
      //     child: Text(
      //       '${staggeredModel.index}',
      //       style: 20.ts,
      //     ));
      widgets.add(_buildStaggeredBoardItem(i));
      // widgets.add(positionedText);
    }
    return widgets;
  }

  // 构建子item
  Widget _buildStaggeredBoardItem(int index) {
    StaggeredItem staggeredModel = _itemList[index];
    Offset? offset = _offsetMap['${staggeredModel.index}'];
    Size? size = _sizeMap['${staggeredModel.index}'];

    return AnimatedPositioned(
        duration: widget.duration,
        left: offset?.dx,
        top: offset?.dy,
        child: widget.canDrag
            ? LongPressDraggable(
                data: staggeredModel.index,
                feedback: Stack(
                    key: GlobalKey(debugLabel: staggeredModel.key),
                    children: [
                      Opacity(
                        opacity: 0.85,
                        child: Container(
                          width: size?.width,
                          height: size?.height,
                          decoration: const BoxDecoration(boxShadow: [
                            BoxShadow(
                                offset: Offset(0, 5),
                                color: Color.fromRGBO(0, 0, 0, 0.5),
                                blurRadius: 25)
                          ]),
                          child: staggeredModel.child,
                        ),
                      ),
                      staggeredModel.canOpen
                          ? Positioned(
                              right: 0,
                              top: 0,
                              child: Container(
                                alignment: Alignment.center,
                                // color: Colors.red,
                                padding:
                                    const EdgeInsets.fromLTRB(6, 0, 0, 10).r,
                                width: 44.w,
                                height: 44.w,
                                child: SvgPicture.asset(
                                    staggeredModel.mainAxisCellCount == 2
                                        ? SVGImage.icCardCollapseCloseSvg
                                        : SVGImage.icCardCollapseOpenSvg,
                                    color: staggeredModel.unfoldCloseColor),
                              ))
                          : Container()
                    ]),
                childWhenDragging: Container(
                  width: size?.width,
                  height: size?.height,
                  decoration: BoxDecoration(
                      color: const Color.fromRGBO(55, 55, 55, 0.5),
                      borderRadius: BorderRadius.circular(25)),
                ),
                onDragStarted: () {
                  _moveStaggeredItem = staggeredModel;
                  // print('=== onDragStarted');
                },
                onDragUpdate: (DragUpdateDetails onDragUpdate) {
                  _dragPosition = onDragUpdate.globalPosition;
                  _dragOffset = onDragUpdate.delta;
                  _autoScroller?.startAutoScrollIfNecessary(
                      _dragTargetRect(size!.width, size.height));

                  // print(onDragUpdate);
                  // print(GlobalKey(debugLabel: staggeredModel.key).position());
                },
                onDragEnd: (details) {
                  _autoScroller?.startAutoScrollIfNecessary(
                      _dragTargetRect(size!.width, size.height));
                },
                onDraggableCanceled: (Velocity velocity, Offset offset) {
                  // print('=== onDraggableCanceled');
                  _moveIndex = -1;
                  _toIndex = -1;
                  // setState(() {
                  //   _draggableItem = null;
                  // });
                  _moveStaggeredItem = null;
                },
                onDragCompleted: () {
                  // print('=== onDragCompleted');
                  _moveIndex = -1;
                  _toIndex = -1;
                  _moveStaggeredItem = null;
                  // setState(() {
                  //   _draggableItem = null;
                  // });
                },
                child: DragTarget(builder: (BuildContext context,
                    List<Object?> candidateData, List<dynamic> rejectedData) {
                  return CardShakeWidget(
                    // key: GlobalKey(debugLabel: staggeredModel.key),
                    startupAnimation: widget.canDrag,
                    child: AnimatedContainer(
                      duration: widget.duration,
                      width: size?.width,
                      height: size?.height,
                      curve: widget.curve,
                      decoration: BoxDecoration(
                          borderRadius: BorderRadius.circular(25.r)),
                      clipBehavior: Clip.antiAlias,
                      child: Stack(children: [
                        staggeredModel.child,
                        Positioned(
                            right: 0,
                            top: 0,
                            child: Container(
                              alignment: Alignment.center,
                              // color: Colors.red,
                              padding: const EdgeInsets.fromLTRB(6, 0, 0, 10).r,
                              width: 44.w,
                              height: 44.w,
                              child: SvgPicture.asset(
                                  staggeredModel.mainAxisCellCount == 2
                                      ? SVGImage.icCardCollapseCloseSvg
                                      : SVGImage.icCardCollapseOpenSvg,
                                  color: staggeredModel.unfoldCloseColor),
                            ).hidden(!staggeredModel.canOpen).onClick(() {
                              for (var i = 0; i < _changeitemList.length; i++) {
                                StaggeredItem itemModel = _changeitemList[i];
                                if (itemModel.index == staggeredModel.index) {
                                  int count = itemModel.mainAxisCellCount!;
                                  if (count == 2) {
                                    count = 1;
                                    _cardOpen = false;
                                  } else {
                                    count = 2;
                                    _cardOpen = true;
                                  }
                                  widget.cardOpenChanged!(
                                      itemModel.index!, _cardOpen);
                                  itemModel.mainAxisCellCount = count;
                                  staggeredModel.mainAxisCellCount = count;
                                  setState(() {
                                    _changeOffsetAndSizeMap();
                                  });
                                  break;
                                }
                              }
                            }))
                      ]),
                    ),
                  );
                }, onWillAccept: (moveData) {
                  var accept = moveData != null;

                  // print('正在移动的key: ${_moveStaggeredItem?.key}');
                  // print('当前位置里的key数组: $_globalKeyList');

                  // 限制不在自己的编辑区域不进行移动操作
                  if (_moveStaggeredItem == null) {
                    accept = false;
                  }

                  if (accept) {
                    _antiShakeProcessing(moveData, staggeredModel.index);
                  }
                  return accept;
                }, onLeave: (moveData) {
                  if (moveData == _moveIndex) {
                    _moveIndex = -1;
                  }
                  if (index == _toIndex) {
                    _toIndex = -1;
                  }
                }))
            : AnimatedContainer(
                duration: widget.duration,
                width: size?.width,
                height: size?.height,
                curve: widget.curve,
                child: staggeredModel.child));
  }

  /// 防抖处理
  void _antiShakeProcessing(moveIndex, toIndex) {
    if (moveIndex == toIndex) {
      return;
    }
    _moveIndex = moveIndex;
    _toIndex = toIndex;
    Future.delayed(const Duration(milliseconds: 200)).then((value) {
      if (_moveIndex == moveIndex && _toIndex == toIndex) {
        _moveIndex = -1;
        _toIndex = -1;
        if (!_controller.isAnimating) {
          _exchangedItem(moveIndex, toIndex);
          _controller.forward();
        } else {
          _controller.reset();
          _exchangedItem(moveIndex, toIndex);
          _controller.forward();
        }
      }
    });
  }

  // 交换数据
  void _exchangedItem(moveIndex, toIndex) {
    // print('更换位置 : moveIndex = $moveIndex, toIndex = $toIndex');

    int changeToIndex = 0;
    int changeMoveIndex = 0;

    if (_changeitemList.isEmpty) {
      _changeitemList.addAll(_itemList);
    }

    for (var i = 0; i < _changeitemList.length; i++) {
      StaggeredItem itemModel = _changeitemList[i];
      if (itemModel.index == moveIndex) {
        changeMoveIndex = i;
      }
      if (itemModel.index == toIndex) {
        changeToIndex = i;
      }
    }
    // print('改变前的数据 $_changeitemList');
    StaggeredItem moveItemModel = _changeitemList.removeAt(changeMoveIndex);
    _changeitemList.insert(changeToIndex, moveItemModel);
    // print('改变后的数据 $_changeitemList');

    _changeOffsetAndSizeMap();
    setState(() {});
  }

// 改变子视图偏移量与大小
  _changeOffsetAndSizeMap() {
    _mainY = widget.padding.top;
    double dx = widget.padding.left;
    double dy = widget.padding.top;
    //  _changeIndex = [];
    for (var i = 0; i < _changeitemList.length; i++) {
      StaggeredItem staggeredModel = _changeitemList[i];
      // 计算item大小
      Size itemSize = _getItemSize(staggeredModel);
      _offsetMap['${staggeredModel.index}'] = Offset(dx, dy);
      _sizeMap['${staggeredModel.index}'] = itemSize;

      double itemMaxY = dy + itemSize.height;

      if (itemMaxY > _mainY) {
        dx = dx + widget.itemSpace + itemSize.width;
        dy = _mainY + (_mainY == widget.padding.top ? 0 : widget.itemSpace);
        if (1.sw - widget.padding.left - widget.padding.right < dx) {
          // print('从最开始排列');
          dx = widget.padding.left;
          dy = _mainY + widget.itemSpace;
        }
        _mainY = itemMaxY;
      } else if (itemMaxY == _mainY) {
        dy = itemMaxY + widget.itemSpace;
        dx = widget.padding.left;
      } else {
        dy = itemMaxY + widget.itemSpace;
      }
    }
    _mainY = _mainY + widget.padding.bottom;
  }

  // 计算子视图的尺寸
  Size _getItemSize(StaggeredItem staggeredModel) {
    double itemWidth = 0;
    double itemHeight = 0;
    // 计算item真实宽度
    itemWidth = _itemMiniWidth * staggeredModel.crossAxisCellCount! +
        widget.itemSpace * (staggeredModel.crossAxisCellCount! - 1);
    itemHeight = _itemMiniHeight * staggeredModel.mainAxisCellCount! +
        widget.itemSpace * (staggeredModel.mainAxisCellCount! - 1);

    return Size(itemWidth, itemHeight);
  }

  // 计算拖拽到边缘位置的偏移量
  Rect _dragTargetRect(double width, double height) {
    Offset origin = _dragPosition - _dragOffset;

    // if (scrollDirection == Axis.horizontal) {
    //   origin = Offset(dragPosition.dx < width ? -1 : origin.dx, origin.dy);
    // } else if (scrollDirection == Axis.vertical) {
    origin = Offset(origin.dx, _dragPosition.dy < height ? -1 : origin.dy);
    // }
    return Rect.fromLTWH(origin.dx, origin.dy, width, height);
  }
}

// 对外开放传值的model
class StaggeredItem {
  StaggeredItem(
      {this.crossAxisCellCount,
      this.mainAxisCellCount,
      this.unfoldCloseColor,
      this.canOpen = true,
      required this.key,
      required this.child});

  int? index;
  String? key;
  int? crossAxisCellCount;
  int? mainAxisCellCount;
  bool canOpen;
  Color? unfoldCloseColor; // 展开合上按钮颜色
  Widget child;

  @override
  String toString() {
    return 'index = $index key = $key crossAxisCellCount = $crossAxisCellCount mainAxisCellCount = $mainAxisCellCount \n';
  }
}
